<?php namespace Common\Helper;

class InputData {

    /**
     * 网络参数
     * @var array
     */
    private static $_inputData = array();

    private static $_files = array();

    private static $singleInstance = null;

    public function __construct(){
        if(!self::$_inputData){
            if( get_magic_quotes_gpc() )
            {
                HelperCommon::prepareGPCData( $_GET );
                HelperCommon::prepareGPCData( $_POST );
            }
            self::$_inputData = HelperArray::arrayMergeRecursiveDistinct( $_GET , $_POST );;
        }
        if( count( $_FILES ) > 0 && !self::$_files )
        {
            foreach( $_FILES as $key => $file )
            {
                if( !is_array( $file['error'] ) )
                {
                    if( $file['error'] != UPLOAD_ERR_OK
                        || ( !defined( 'IN_TEST' ) && !is_uploaded_file( $file['tmp_name'] ) ) )
                    {
                        continue;
                    }

                    self::$_files[$key] = $file['tmp_name'];
                }
                else
                {
                    foreach( $file['error'] as $subKey => $error )
                    {
                        if( $error['error'] != UPLOAD_ERR_OK
                            || ( !defined( 'IN_TEST' ) && !is_uploaded_file( $file['tmp_name'][$subKey] ) ) )
                        {
                            continue;
                        }

                        self::$_files[$key][$subKey] = $file['tmp_name'][$subKey];
                    }
                }
            }
        }

    }

    /**
     * @return InputData|null
     */
    public static function getInstance(){
        if(self::$singleInstance===null){
            self::$singleInstance = new self();
        }
        return self::$singleInstance;
    }

    /**
     * @param $key
     * @param int $defaultValue
     * @param bool $isThrowException
     * @param int $errorCode
     * @return int
     */
    public function getInteger($key,$defaultValue=0,$isThrowException=false,$errorCode=0){
        if(!self::$_inputData[$key]){
            $this->throwException($isThrowException,$errorCode);
            return $defaultValue;
        }
        return (integer)self::$_inputData[$key];
    }

    /**
 * @param $key
 * @param int $defaultValue
 * @param bool $isThrowException
 * @param int $errorCode
 * @return int
 */
    public function getPositiveInteger($key,$defaultValue=0,$isThrowException=false,$errorCode=0){
        if(!self::$_inputData[$key]||($value=(integer)self::$_inputData[$key])<=0){
            $this->throwException($isThrowException,$errorCode);
            return $defaultValue;
        }
        return $value;
    }

    /**
     * @param $key
     * @param bool $defaultValue
     * @param bool $isThrowException
     * @param int $errorCode
     * @return boolean
     */
    public function getBoolean($key,$defaultValue=false,$isThrowException=false,$errorCode=0){
        if(!self::$_inputData[$key]){
            $this->throwException($isThrowException,$errorCode);
            return $defaultValue;
        }
        return self::$_inputData[$key] ? true : false;
    }

    /**
     * @param $key
     * @param float $defaultValue
     * @param bool $isThrowException
     * @param int $errorCode
     * @return float
     */
    public function getFloat($key,$defaultValue=0.0,$isThrowException=false,$errorCode=0){
        if(!self::$_inputData[$key]){
            $this->throwException($isThrowException,$errorCode);
            return $defaultValue;
        }
        return (float)self::$_inputData[$key];
    }

    /**
     * @param $key
     * @param float $defaultValue
     * @param bool $isThrowException
     * @param int $errorCode
     * @return float
     */
    public function getPositiveFloat($key,$defaultValue=0.0,$isThrowException=false,$errorCode=0){
        if(!self::$_inputData[$key]||($value=(float)self::$_inputData[$key])<=0){
            $this->throwException($isThrowException,$errorCode);
            return $defaultValue;
        }
        return $value;
    }

    /**
     * @param $key
     * @param string $defaultValue
     * @param bool $isThrowException
     * @param int $errorCode
     * @return float
     */
    public function getString($key,$defaultValue='',$isThrowException=false,$errorCode=0){
        if(!self::$_inputData[$key]){
            $this->throwException($isThrowException,$errorCode);
            return $defaultValue;
        }
        return HelperString::encode(self::$_inputData[$key]);
    }

    /**
     * @param $key
     * @param array $defaultValue
     * @param bool $isThrowException
     * @param int $errorCode
     * @return float
     */
    public function getArray($key,$defaultValue=array(),$isThrowException=false,$errorCode=0){
        if(!self::$_inputData[$key]||!is_array(self::$_inputData[$key])){
            $this->throwException($isThrowException,$errorCode);
            return $defaultValue;
        }
        return self::$_inputData[$key];
    }

    /**
     * @param $key
     * @param string $defaultValue
     * @param bool $isThrowException
     * @param int $errorCode
     * @return float
     */
    public function getTrimString($key,$defaultValue='',$isThrowException=false,$errorCode=0){
        if(!self::$_inputData[$key]||strlen($value=trim(HelperString::encode(self::$_inputData[$key])))<=0){
            $this->throwException($isThrowException,$errorCode);
            return $defaultValue;
        }
        return $value;
    }

    /**
     * 获取上传的图片文件
     * @param	string	$key	字段名
     * @param	string	$defaultPath	默认值
     * @param	boolean	$isThrowException	是否抛出异常
     * @param	int	$errorCode	错误码
     * @param	boolean	$isCompress	是否到达压缩规格后就自动压缩
     * @param	boolean	$isWriteWaterMark	是否需要添加水印
     * @param	int	$width	指定宽度
     * @param	int	$height	指定高度
     * @param	string	$appendImage	追加的图片地址
     * @param	string	$forceImageType	强制转换的图片类型
     * @return	array(
     * 				path :string
     * 				width: int
     * 				height: int
     * 				binary: byte[]
     * 				tmpPath: string
     * 			)
     */
    public function getUploadImage(
        $key ,
        $defaultPath = '' ,
        $isThrowException = false ,
        $errorCode = 0 ,
        $isCompress = false ,
        $isWriteWaterMark = false ,
        $width = 0 ,
        $height = 0 ,
        $appendImage = '' ,
        $forceImageType = 'jpg' )
    {
        if( !self::$_files[$key] )
        {
            $this->throwException( $key , $isThrowException , $errorCode );

            return $this->_getDefaultImageParameters( $defaultPath );
        }

        return $this->_uploadImage( $key , self::$_files[$key] , $defaultPath ,
            $isThrowException , $errorCode ,
            $isCompress , $isWriteWaterMark , $width , $height ,
            $appendImage , $forceImageType );
    }


    /**
     * 获取默认图像参数
     * @param	string	$path	路径
     * @return	array(
     * 				path :string
     * 				width: int
     * 				height: int
     * 				binary: byte[]
     * 				tmpPath: string
     * 			)
     */
    private function _getDefaultImageParameters( $path )
    {
        if( empty( $path ) )
        {
            return array(
                'path' => $path ,
                'width' => 0 ,
                'height' => 0 ,
                'binary' => '' ,
                'tmpPath' => '' ,
            );
        }

        $binaryContent = file_get_contents( $path );
        $image = HelperThumbnail::getInstance();
        $image->setSrcImg( $binaryContent , HelperThumbnail::checkImgType( $binaryContent ) );

        return array(
            'path' => $path ,
            'width' => $image->src_w ,
            'height' => $image->src_h ,
            'binary' => $binaryContent ,
            'tmpPath' => $path ,
        );
    }

    /**
     * 获取上传的图片文件
     * @param	string	$key	字段名
     * @param	string	$tmpPath	临时文件目录
     * @param	string	$defaultPath	默认值
     * @param	boolean	$isThrowException	是否抛出异常
     * @param	int	$errorCode	错误码
     * @param	boolean	$isCompress	是否到达压缩规格后就自动压缩
     * @param	boolean	$isWriteWaterMark	是否需要添加水印
     * @param	int	$width	指定宽度
     * @param	int	$height	指定高度
     * @param	string	$appendImage	追加的图片地址
     * @param	string	$forceImageType	强制转换的图片类型
     * @return	array(
     * 				path :string
     * 				width: int
     * 				height: int
     * 				binary: byte[]
     * 				tmpPath: string
     * 			)
     */
    private function _uploadImage( $key , $tmpPath ,
        $defaultPath = '' ,
        $isThrowException = false ,
        $errorCode = 0 ,
        $isCompress = false ,
        $isWriteWaterMark = false ,
        $width = 0 ,
        $height = 0 ,
        $appendImage = '' ,
        $forceImageType = 'jpg' )
    {
        //上传图片
        $uploadResult = HelperImage::getInstance()
            ->setBinaryContent(
                $binaryContent = file_get_contents( $tmpPath )
            )
            ->setIsCompress( $isCompress )
            ->setIsWriteWaterMark( $isWriteWaterMark )
            ->setWidth( $width )
            ->setHeight( $height )
            ->setAppendImage( $appendImage )
            ->setForceType( $forceImageType )
            ->upload();

        //图片类型错误
        if( !defined( 'IN_TEST' ) && !$uploadResult['path'] )
        {
            $this->throwException( $key , $isThrowException , $errorCode );

            return $this->_getDefaultImageParameters( $defaultPath );
        }

        return array(
            'path' => $uploadResult['path'] ,
            'width' => $uploadResult['width'] ,
            'height' => $uploadResult['height'] ,
            'binary' => $binaryContent ,
            'tmpPath' => $tmpPath ,
        );
    }

    /**
     * @param $key
     * @param $isThrowException
     * @param $errorCode
     */
    private function throwException( $key , $isThrowException , $errorCode ){
        if($isThrowException){
            E($key.'值出错',$errorCode);
        }
    }
}
